﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using CommunityToolkit.Mvvm.ComponentModel;
using MeasureAbstract.Base;
using MeasureAbstract.IMotionDevice;

namespace MeasureAbstract.IVectorNetworkAnalyzer
{
    [INotifyPropertyChanged]
    public abstract partial class IVectorNetworkAnalyzer : IDeviceBase
    {
        #region 父类
        public abstract string Name { get; }
        public abstract string Vender { get; }
        public abstract string Model { get; }
        public abstract string Description { get; }

        /// <summary>
        /// 端口数量
        /// </summary>
        public abstract int PortCount { get; }


        public bool _RadioFrequencyState = false;
        public bool RadioFrequencyState
        {
            get
            {
                return _RadioFrequencyState;
            }
            set
            {
                SetProperty(ref _RadioFrequencyState, value);
            }
        }


        public bool _ConnectState = false;
        public bool ConnectState
        {
            get
            {
                return _ConnectState;
            }
            set
            {
                SetProperty(ref _ConnectState, value);
            }
        }

        public bool _MalfunctionState = false;
        public bool MalfunctionState
        {
            get
            {
                return _MalfunctionState;
            }
            set
            {
                SetProperty(ref _MalfunctionState, value);
            }
        }


        //设备操作
        public abstract void Connect();
        public abstract void DisConnect();
        public abstract void ReSet();

        #endregion


        #region 设备参数区


        /// <summary>
        /// 起止频率模式
        /// </summary>
        [ObservableProperty]
        private bool seMode = true;

        /// <summary>
        /// 中频跨度模式
        /// </summary>
        [ObservableProperty]
        private bool cbMode = false;

        /// <summary>
        /// 列表模式
        /// </summary>
        [ObservableProperty]
        private bool listMode = false;

        /// <summary>
        /// 设备参数
        /// </summary>
        public VectorNetworkAnalyzerConfig? Config { get; set; }

        /// <summary>
        /// 起始频率
        /// </summary>
        [ObservableProperty]
        private double startFrequency = 100;
        /// <summary>
        /// 起始频率单位
        /// </summary>
        [ObservableProperty]
        private string startFrequencyUnit = "MHz";

        /// <summary>
        /// 结束频率
        /// </summary>
        [ObservableProperty]
        private double endFrequency = 200;
        /// <summary>
        /// 结束频率单位
        /// </summary>
        [ObservableProperty]
        private string endFrequencyUnit = "MHz";

        /// <summary>
        /// 频率单位
        /// </summary>
        public abstract ObservableCollection<string> Unit { get; }

        /// <summary>
        /// 频点数量
        /// </summary>
        [ObservableProperty]
        private int frequencyCount = 21;

        /// <summary>
        /// 中心频率
        /// </summary>
        [ObservableProperty]
        private double centerFrequency = 200;
        /// <summary>
        /// 中心频率单位
        /// </summary>
        [ObservableProperty]
        private string centerFrequencyUnit = "MHz";

        /// <summary>
        /// 频率跨度
        /// </summary>
        [ObservableProperty]
        private double bandFrequency = 200;
        /// <summary>
        /// 频率跨度单位
        /// </summary>
        [ObservableProperty]
        private string bandFrequencyUnit = "MHz";


        /// <summary>
        /// 频率列表
        /// </summary>
        [ObservableProperty]
        private string frequencys = "100,200,300";



        /// <summary>
        /// S参数
        /// </summary>
        [ObservableProperty]
        private string sParameter = "S21";


        /// <summary>
        /// 支持的数据格式
        /// </summary>
        public abstract ObservableCollection<string> DataFormatList { get; }


        /// <summary>
        /// 选择的数据格式
        /// </summary>
        [ObservableProperty]
        private ObservableCollection<string> selectedDataFormats = new ObservableCollection<string>() { "对数幅度", "相位" };

        /// <summary>
        /// 平滑
        /// </summary>
        [ObservableProperty]
        private int smooth = 3;

        /// <summary>
        /// 平均
        /// </summary>
        [ObservableProperty]
        private int average = 5;

        /// <summary>
        /// 中频带宽
        /// </summary>
        [ObservableProperty]
        private int iFBW = 10;

        /// <summary>
        /// 中频带宽单位
        /// </summary>
        [ObservableProperty]
        private string iFBWUnit = "KHz";

        /// <summary>
        /// 使用或不使用射频功能
        /// </summary>
        [ObservableProperty]
        private bool radioEnable = true;

        /// <summary>
        /// 发射功率
        /// </summary>
        [ObservableProperty]
        private double outputPower_dBm = -20;

        /// <summary>
        /// 使用设备间联动
        /// </summary>
        [ObservableProperty]
        public bool deviceInteractEnable = false;

        /// <summary>
        /// 使用触发输入
        /// </summary>
        [ObservableProperty]
        public bool triggerInEnable = true;

        /// <summary>
        /// 选择的触发输入口
        /// </summary>
        public abstract string SelectedTriggerInPort { get; set; }

        /// <summary>
        /// 设备的触发输入接口列表
        /// </summary>
        public abstract ObservableCollection<string> TriggerInPorts { get; }

        /// <summary>
        /// 选择的触发输入信号
        /// </summary>
        public abstract string SelectedTriggerInSignal { get; set; }

        /// <summary>
        /// 设备的触发输入信号列表
        /// </summary>
        public abstract ObservableCollection<string> TriggerInSignals { get; }

        /// <summary>
        /// 选择的触发输入信号脉冲宽度
        /// </summary>
        public abstract string SelectedTriggerInSignalWidth { get; set; }

        /// <summary>
        /// 测量两点的驻留时间
        /// </summary>
        public abstract string DWell { get; set; }

        /// <summary>
        /// 选择的触发输入相应动作
        /// </summary>
        public abstract string SelectedTriggerInAction { get; set; }

        /// <summary>
        /// 设备的触发输入动作列表
        /// </summary>
        public abstract ObservableCollection<string> TriggerInActions { get; }

        /// <summary>
        /// 使用触发输出
        /// </summary>
        [ObservableProperty]
        public bool triggerOutEnable = true;

        /// <summary>
        /// 选择的触发输出口
        /// </summary>
        public abstract string SelectedTriggerOutPort { get; set; }

        /// <summary>
        /// 设备的触发输出接口列表
        /// </summary>
        public abstract ObservableCollection<string> TriggerOutPorts { get; }

        /// <summary>
        /// 选择的触发输出信号
        /// </summary>
        public abstract string SelectedTriggerOutSignal { get; set; }

        /// <summary>
        /// 选择的触发输出信号脉冲宽度
        /// </summary>
        public abstract string SelectedTriggerOutSignalWidth { get; set; }

        /// <summary>
        /// 设备的触发输出信号列表
        /// </summary>
        public abstract ObservableCollection<string> TriggerOutSignals { get; }

        /// <summary>
        /// 选择的触发输出动作时机
        /// </summary>
        public abstract string SelectedTriggerOutTime { get; set; }

        /// <summary>
        /// 设备的触发输出动作时机列表
        /// </summary>
        public abstract ObservableCollection<string> TriggerOutTimes { get; }


        #endregion


        #region 设备行为

        /// <summary>
        /// 测量一次
        /// </summary>
        /// <param name="ChannelNumber">通道号，默认测量所有通道</param>
        public abstract void MeasureOnce(int ChannelNumber = int.MaxValue);

        /// <summary>
        /// 读取某个通道的某个测量的数据
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="MeasureName">测量名称</param>
        /// <param name="Data">数据</param>
        public abstract void ReadData(int ChannelNumber, string MeasureName, out double[] Data);

        /// <summary>
        /// 开启关闭射频
        /// </summary>
        /// <param name="Open">true开启射频，false关闭射频</param>
        public abstract void OutPut(bool Open);

        /// <summary>
        /// 创建一个测量
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="VNAMeasurementName">测量名称</param>
        /// <param name="MeasuredParameters">测量参数</param>
        /// <returns></returns>
        public abstract int CreateMeasurement(int ChannelNumber, string VNAMeasurementName, string MeasuredParameters);

        /// <summary>
        /// 打开或创建一个窗口
        /// </summary>
        /// <param name="WindowNumber">窗口号</param>
        /// <returns></returns>
        public abstract int OpenWindow(int WindowNumber);

        /// <summary>
        /// 将某个测量显示在某个窗口的某个轨迹
        /// </summary>
        /// <param name="WindowNumber">通道号</param>
        /// <param name="TraceNumber">轨迹号ram>
        /// <param name="VNAMeasurementName">测量名称ram>
        /// <returns></returns>
        public abstract int DisplayMeasurement(int WindowNumber, int TraceNumber, string VNAMeasurementName);

        /// <summary>
        /// 从窗口删除一条轨迹，测量还在
        /// </summary>
        /// <param name="WindowNumber">窗口号</param>
        /// <param name="TraceNumber">轨迹</param>
        /// <returns></returns>
        public abstract int DeleteMeasurement(int WindowNumber, int TraceNumber);

        /// <summary>
        /// 选中一个测量
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="VNAMeasurementName">测量名称</param>
        /// <returns></returns>
        public abstract int SelectMeasurement(int ChannelNumber, string VNAMeasurementName);

        /// <summary>
        /// 设置某个测量的数据类型
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="VNAMeasurementName">测量名称</param>
        /// <param name="DataFormat">数据格式，如幅度，相位等</param>
        /// <returns></returns>
        public abstract int SetDataFormat(int ChannelNumber, string VNAMeasurementName, string DataFormat);

        /// <summary>
        /// 设置扫描类型
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="VNAMeasurementName">测量名称</param>
        /// <param name="ScanType">扫描类型</param>
        /// <returns></returns>
        public abstract int SetScanType(int ChannelNumber, string VNAMeasurementName, string ScanType);

        /// <summary>
        /// 设置起始频率
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="VNAMeasurementName">测量名称</param>
        /// <param name="StartFrequency">起始频率</param>
        /// <param name="Unit">单位</param>
        /// <returns></returns>
        public abstract int SetStartFrequency(int ChannelNumber, string VNAMeasurementName, long StartFrequency, string Unit = "Hz");

        /// <summary>
        /// 设置结束频率
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="VNAMeasurementName">测量名称</param>
        /// <param name="EndFrequency">结束频率</param>
        /// <param name="Unit">单位</param>
        /// <returns></returns>
        public abstract int SetEndFrequency(int ChannelNumber, string VNAMeasurementName, long EndFrequency, string Unit = "Hz");

        /// <summary>
        /// 设置中心频率
        /// </summary>
        /// <param name="ChannelNumber">通道号<param>
        /// <param name="VNAMeasurementName">测量名称</param>
        /// <param name="CenterFrequency">中心频率</param>
        /// <param name="Unit">单位</param>
        /// <returns></returns>
        public abstract int SetCenterFrequency(int ChannelNumber, string VNAMeasurementName, long CenterFrequency, string Unit = "Hz");

        /// <summary>
        /// 设置频率跨度
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="VNAMeasurementName">测量名称</param>
        /// <param name="BandWidth">带宽</param>
        /// <param name="Unit">单位</param>
        /// <returns></returns>
        public abstract int SetFrequencyBandWidth(int ChannelNumber, string VNAMeasurementName, long BandWidth, string Unit = "Hz");

        /// <summary>
        /// 设置扫描点数
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="VNAMeasurementName">测量名称</param>
        /// <param name="PointCount">测量点数</param>
        /// <returns></returns>
        public abstract int SetScanPoints(int ChannelNumber, string VNAMeasurementName, int PointCount);

        /// <summary>
        /// 设置发射功率
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="MeasurementName">测量名称</param>
        /// <param name="OutputPower_dBm">发射功率</param>
        /// <returns></returns>
        public abstract int SetOutputPower(int ChannelNumber, double OutputPower_dBm = -20);

        /// <summary>
        /// 设置中频带宽
        /// </summary>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="Bandwidth">带宽</param>
        /// <param name="Unit">单位</param>
        /// <returns></returns>
        public abstract int SetIntermediateFrequencyBandwidth(int ChannelNumber, long Bandwidth, string Unit = "Hz");

        /// <summary>
        /// 设置某个测量的平滑
        /// </summary>
        /// <param name="Enable">是否开启</param>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="Aperture">平滑值</param>
        /// <returns></returns>
        public abstract int SetSmooth(bool Enable, int ChannelNumber, int Points);

        /// <summary>
        /// 设置某个测量的平均次数
        /// </summary>
        /// <param name="Enable">是否开启</param>
        /// <param name="ChannelNumber">通道号</param>
        /// <param name="Count">平均数量</param>
        /// <returns></returns>
        public abstract int SetAverage(bool Enable, int ChannelNumber, int Count);

        /// <summary>
        /// 设置Y轴为自动比例
        /// </summary>
        /// <param name="WindowNumber">窗口号</param>
        /// <param name="TraceNumber">轨迹号</param>
        /// <returns></returns>
        public abstract int SetYScaleAuto(int WindowNumber, int TraceNumber);

        /// <summary>
        /// 设置触发源
        /// </summary>
        /// <param name="TriggerSource">内部INT，外部EXT，手动MAN，总线BUS</param>
        /// <returns></returns>
        public abstract int SetTriggerSource(TriggerSource TriggerSource);

        /// <summary>
        /// 设置触发范围
        /// </summary
        /// <param name="TriggerScope">ONE触发一个通道，ALL触发全部</param>
        /// <returns></returns>
        public abstract int SetTriggerScope(TriggerScope TriggerScope);


        /// <summary>
        /// 设置触发输入
        /// </summary>
        /// <param name="Interface">哪个口作为触发输入的接口</param>
        /// <param name="TriggerSignalType">触发信号的类型</param>
        /// <param name="Delay_ms">收到触发信号后，延时一定时间进行进行动作</param>
        /// <returns></returns>
        public abstract int SetTriggerInput(string Interface, TriggerSignalType TriggerSignalType, double Width, double Delay_ms = 0);

        /// <summary>
        /// 设置触发输出
        /// </summary>
        /// <param name="Enable">使能</param>
        /// <param name="Interface">哪个接口作为触发输出</param>
        /// <param name="ChannelNumber">哪个通道</param>
        /// <param name="TriggerSignalType">触发信号类型</param>
        /// <param name="Width">信号宽度</param>
        /// <returns></returns>
        public abstract int SetTriggerOut(bool Enable, string Interface, int ChannelNumber, string time, TriggerSignalType TriggerSignalType, double Width);

        /// <summary>
        /// 设置扫描模式
        /// </summary>
        /// <param name="SweepMode">连续还是保持</param>
        /// <returns></returns>
        public abstract int SetSweepMode(SweepMode SweepMode = SweepMode.连续);

        /// <summary>
        /// 触发一次的扫描范围
        /// </summary>
        /// <param name="SweepScope">整个通道的所有测量;同一端口的测量;一个点</param>
        /// <returns></returns>
        public abstract int SetSweepScope(SweepScope SweepScope = SweepScope.通道);


        /// <summary>
        /// 等待矢网操作完成
        /// </summary>
        /// <param name="PollingTime_ms">轮询时间每隔这么长时间询问一次矢网</param>
        /// <returns></returns>
        public abstract int Wait(int PollingTime_ms);

        /// <summary>
        /// 将数据格式转换为矢网可以识别的格式
        /// </summary>
        /// <param name="DataFormatName"></param>
        /// <returns></returns>
        public abstract string ConvertDataFormatName(string DataFormatName);


        /// <summary>
        /// 获取错误
        /// </summary>
        /// <param name="ErrorInfo"></param>
        /// <returns></returns>
        public abstract int GetError(ref string ErrorInfo);
        #endregion
        /// <summary>
        /// 等待操作执行完成
        /// </summary>
        /// <param name="WaitMode"></param>
        /// <returns></returns>
        public virtual bool ActionDone(int TimeOut_S, WaitMode WaitMode = WaitMode.等应答)
        {



            return true;
        }



        /// <summary>
        /// 获取数据类型的索引号，以此作为测量名称
        /// </summary>
        /// <param name="DataFormat">数据类型</param>
        /// <param name="DataFormatList">支持的数据类型列表</param>
        /// <returns></returns>
        public virtual string GetVNAMeasureName(string DataFormat, ObservableCollection<string> DataFormatList)
        {
            string Name = "";
            if (DataFormatList == null)
            {
                throw new ArgumentNullException(nameof(DataFormatList));
            }
            if (string.IsNullOrEmpty(DataFormat))
            {
                throw new ArgumentNullException(nameof(DataFormat));
            }

            int Index = DataFormatList.IndexOf(DataFormat);
            if (Index == -1)
            {
                throw new Exception($"创建轨迹名称失败，不支持的数据格式{DataFormat}!");
            }
            else
            {
                return Index.ToString();
            }
        }

        public long GetHZ(double Value, string Unit)
        {
            long NewValue = 0;
            switch (Unit.ToUpper())
            {
                case "HZ":
                    NewValue = (long)Value;
                    break;
                case "KHZ":
                    NewValue = (long)(Value * 1000);
                    break;
                case "MHZ":
                    NewValue = (long)(Value * 1000000);
                    break;
                case "GHZ":
                    NewValue = (long)(Value * 1000000000);
                    break;
            }
            return NewValue;
        }


    }


    public sealed partial class VectorNetworkAnalyzerConfig : CommunicationConfig
    {

    }

    


  
}
